
#ifndef DB_HPP
#define DB_HPP
#include <vector>
#include <string>
#include <map>
#include <functional>

class DB
{
public:
    // Get returns nil iff key doesn't exist.
    // A nil key is interpreted as an empty byteslice.
    virtual const std::vector<unsigned char> get(const std::vector<unsigned char>& key) = 0;
    virtual bool has(const std::vector<unsigned char>& key) = 0;

    // Set sets the key.
    virtual void set(const std::vector<unsigned char>& key, const std::vector<unsigned char>& value) = 0;
    virtual void setSync(const std::vector<unsigned char>& key,const std::vector<unsigned char>& value) = 0;

    // Delete deletes the key.
    virtual void deleteItem(const std::vector<unsigned char>& key) = 0;
    virtual void deleteItemSync(const std::vector<unsigned char>& key) = 0;

    virtual void close() = 0;

    virtual ~DB() = 0;
};


typedef std::string DBBackendType;

const DBBackendType kLevelDBBackend = "leveldb"; 
const DBBackendType kCLevelDBBackend = "cleveldb";
const DBBackendType kGoLevelDBBackend = "goleveldb";
const DBBackendType kMemDBBackend = "memdb";
const DBBackendType kSqliteDBBackend = "sqlitedb";

typedef std::function<DB* (std::string name, std::string dir)> dbCreator;

std::map<DBBackendType, dbCreator> backends;

void registerDBCreator(DBBackendType& backend, dbCreator& creator)
{
    backends[backend] = creator;
}

DB* newDB(std::string name, DBBackendType backend, std::string dir)
{
    return backends[backend](name, dir);
}

#endif // !DB_HPP
